package smsapi.auth;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import smsapi.util.Signer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.TreeMap;

public class AuthInterceptor implements HandlerInterceptor {
    @Value("${smsapi.publickeypem:}")
    String publickeypem;

    @Override
    public boolean preHandle(
            HttpServletRequest request,
            HttpServletResponse response,
            Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod hm = (HandlerMethod) handler;
            // 判断类上的注解
            boolean check = false;
            CheckAuth classAuth = hm.getBeanType().getAnnotation(CheckAuth.class);
            if (classAuth != null) {
                check = classAuth.check();
            }
            // 方法是否有注解
            CheckAuth methodAuth = hm.getMethodAnnotation(CheckAuth.class);
            if (methodAuth != null) {
                check = methodAuth.check();
            }
            if (check) {
                String timestamp = request.getHeader("timestamp");
                String nonce = request.getHeader("nonce");
                String companyNo = request.getHeader("companyNo");
                String loginName = request.getHeader("loginName");
                String signature = request.getHeader("signature");
                String data = getBody(request);
                String content = getSignCheckContent(timestamp, nonce, companyNo, data);
                if(!Signer.verify(content, signature, publickeypem)){
                    response.sendError(HttpServletResponse.SC_FORBIDDEN,"验签失败!");
                    return false;
                }
            }
        }
        return true;
    }

    private String getSignCheckContent(String timestamp, String nonce, String companyNo, String data) throws JsonProcessingException {
        Map<String, String> sortedMap = new TreeMap<>();
        sortedMap.put("timestamp", timestamp);
        sortedMap.put("nonce", nonce);
        sortedMap.put("companyNo", companyNo);
        sortedMap.put("data", data);
        String content = Signer.getSignCheckContent(sortedMap);
        return content;
    }

    private String getBody(HttpServletRequest request) {
        String body = "";
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        InputStream inputStream = null;
        try {
            inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        body = stringBuilder.toString();
        return body;
    }
}